# -*- coding: utf-8 -*-
"""
用户系统 - 视图函数
"""

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.core.mail import send_mail
from django.conf import settings
from django.core.cache import cache
from django.db import transaction
from .models import User, UserFollow, PrivateMessage
from .forms import UserRegistrationForm, UserLoginForm, UserProfileForm
import json
import random
import string


def login_view(request):
    """登录页面"""
    if request.user.is_authenticated:
        return redirect('home')
    
    if request.method == 'POST':
        try:
            # 支持JSON和表单两种数据格式
            if request.content_type == 'application/json':
                data = json.loads(request.body)
                username = data.get('username', '').strip()
                password = data.get('password', '')
                remember = data.get('remember')
            else:
                username = request.POST.get('username', '').strip()
                password = request.POST.get('password', '')
                remember = request.POST.get('remember')
            
            # 打印调试信息（开发环境）
            if settings.DEBUG:
                print(f"🔐 登录尝试 - 用户名: {username}, 密码长度: {len(password) if password else 0}")
            
            # 验证必填字段
            if not username or not password:
                return JsonResponse({
                    'code': 400,
                    'message': '用户名和密码不能为空'
                }, status=400)
            
            # 支持用户名、邮箱、手机号登录（使用自定义认证后端）
            user = authenticate(request, username=username, password=password)
            
            if user is not None:
                if not user.is_active:
                    return JsonResponse({
                        'code': 400,
                        'message': '账号已被禁用，请联系管理员'
                    }, status=400)
                
                # 登录成功
                login(request, user)
                
                # 设置session过期时间
                if not remember:
                    request.session.set_expiry(0)  # 浏览器关闭时过期
                else:
                    request.session.set_expiry(1209600)  # 2周
                
                # 获取next参数
                next_url = request.GET.get('next', '/')
                
                if settings.DEBUG:
                    print(f"✅ 登录成功 - 用户: {user.username}, 跳转到: {next_url}")
                
                return JsonResponse({
                    'code': 200,
                    'message': '登录成功',
                    'redirect': next_url
                })
            else:
                if settings.DEBUG:
                    print(f"❌ 登录失败 - 用户名或密码错误")
                return JsonResponse({
                    'code': 400,
                    'message': '用户名或密码错误'
                }, status=400)
        
        except json.JSONDecodeError:
            return JsonResponse({
                'code': 400,
                'message': '数据格式错误'
            }, status=400)
        except Exception as e:
            if settings.DEBUG:
                print(f"❌ 登录异常: {type(e).__name__}: {e}")
            return JsonResponse({
                'code': 500,
                'message': f'登录失败：{str(e)}'
            }, status=500)
    
    return render(request, 'users/login.html')


def register_view(request):
    """注册页面 - 使用邮箱验证"""
    if request.user.is_authenticated:
        return redirect('home')
    
    if request.method == 'POST':
        try:
            # 解析JSON数据
            data = json.loads(request.body)
            
            # 验证必填字段（邮箱、验证码、用户名、密码、昵称）
            required_fields = ['username', 'password1', 'password2', 'email', 'code', 'nickname']
            for field in required_fields:
                if not data.get(field):
                    return JsonResponse({
                        'code': 400,
                        'message': f'{field}不能为空'
                    }, status=400)
            
            # 验证邮箱验证码
            email = data['email'].strip()
            code = data['code'].strip()
            cache_key = f'email_code_{email}'
            cached_code = cache.get(cache_key)
            
            if not cached_code:
                return JsonResponse({
                    'code': 400,
                    'message': '验证码已过期，请重新获取'
                }, status=400)
            
            if cached_code != code:
                return JsonResponse({
                    'code': 400,
                    'message': '验证码错误'
                }, status=400)
            
            # 验证两次密码是否一致
            if data['password1'] != data.get('password2'):
                return JsonResponse({
                    'code': 400,
                    'message': '两次输入的密码不一致'
                }, status=400)
            
            # 验证密码长度
            if len(data['password1']) < 6:
                return JsonResponse({
                    'code': 400,
                    'message': '密码长度至少6位'
                }, status=400)
            
            # 验证用户名格式
            username = data['username'].strip()
            if len(username) < 4 or len(username) > 20:
                return JsonResponse({
                    'code': 400,
                    'message': '用户名长度应在4-20个字符之间'
                }, status=400)
            
            # 检查用户名是否已存在
            if User.objects.filter(username=username).exists():
                return JsonResponse({
                    'code': 400,
                    'message': '用户名已存在'
                }, status=400)
            
            # 检查邮箱是否已存在
            if User.objects.filter(email=email).exists():
                return JsonResponse({
                    'code': 400,
                    'message': '邮箱已被注册'
                }, status=400)
            
            # 手机号为可选字段
            phone = data.get('phone', '').strip()
            if phone:
                import re
                if not re.match(r'^1[3-9]\d{9}$', phone):
                    return JsonResponse({
                        'code': 400,
                        'message': '请输入正确的手机号码'
                    }, status=400)
                
                if User.objects.filter(phone=phone).exists():
                    return JsonResponse({
                        'code': 400,
                        'message': '手机号已被注册'
                    }, status=400)
            
            # 使用事务创建用户
            with transaction.atomic():
                # 创建用户
                user = User.objects.create_user(
                    username=username,
                    password=data['password1'],
                    phone=phone if phone else None,
                    nickname=data['nickname'].strip(),
                    email=email,
                    interests=data.get('interests', '')
                )
                
                # 初始化隐私设置
                user.init_privacy_settings()
                
                # 发送新用户注册积分
                user.points = 100
                user.save()
            
            # 删除已使用的验证码
            cache.delete(cache_key)
            
            # 发送欢迎邮件
            try:
                send_mail(
                    '欢迎加入本地有约',
                    f'亲爱的 {user.nickname}，欢迎加入本地有约平台！\n\n您已成功注册并获得100积分的新手奖励，快去探索精彩的活动吧！',
                    settings.DEFAULT_FROM_EMAIL,
                    [user.email],
                    fail_silently=True,
                )
            except Exception as e:
                print(f'邮件发送失败: {e}')
            
            return JsonResponse({
                'code': 200,
                'message': '注册成功！已赠送100积分'
            })
            
        except json.JSONDecodeError:
            return JsonResponse({
                'code': 400,
                'message': '数据格式错误'
            }, status=400)
        except Exception as e:
            return JsonResponse({
                'code': 500,
                'message': f'注册失败：{str(e)}'
            }, status=500)
    
    return render(request, 'users/register.html')


def logout_view(request):
    """退出登录"""
    logout(request)
    messages.success(request, '已退出登录')
    return redirect('home')


def profile_view(request, user_id):
    """用户个人中心"""
    from activities.models import Activity, ActivityRegistration
    from points.models import DailyCheckin, PointRecord
    from django.db.models import Count, Q
    from datetime import datetime, timedelta
    
    profile_user = get_object_or_404(User, id=user_id)
    
    # 检查隐私设置
    if request.user != profile_user:
        # 这里可以根据隐私设置过滤显示内容
        pass
    
    # 统计数据
    # 创建的活动数量
    created_activities_count = Activity.objects.filter(creator=profile_user).count()
    
    # 参加的活动数量
    joined_activities_count = ActivityRegistration.objects.filter(
        user=profile_user,
        status='registered'
    ).count()
    
    # 关注数和粉丝数
    following_count = UserFollow.objects.filter(follower=profile_user).count()
    followers_count = UserFollow.objects.filter(following=profile_user).count()
    
    # 连续签到天数
    checkin_records = DailyCheckin.objects.filter(user=profile_user).order_by('-checkin_date')
    consecutive_days = 0
    if checkin_records.exists():
        last_date = checkin_records.first().checkin_date
        if last_date == datetime.now().date():
            consecutive_days = 1
            for record in checkin_records[1:]:
                if (last_date - record.checkin_date).days == 1:
                    consecutive_days += 1
                    last_date = record.checkin_date
                else:
                    break
    
    # 本月签到次数
    month_checkins = DailyCheckin.objects.filter(
        user=profile_user,
        checkin_date__year=datetime.now().year,
        checkin_date__month=datetime.now().month
    ).count()
    
    # 积分记录（最近10条）
    recent_points = PointRecord.objects.filter(
        user=profile_user
    ).order_by('-created_at')[:10]
    
    # 最近活动（最近5个）
    recent_activities = Activity.objects.filter(
        Q(creator=profile_user) | Q(registrations__user=profile_user)
    ).distinct().order_by('-created_at')[:5]
    
    # 处理兴趣标签
    interests_list = []
    if profile_user.interests:
        interests_list = [i.strip() for i in profile_user.interests.split(',') if i.strip()]
    
    context = {
        'profile_user': profile_user,
        'created_activities_count': created_activities_count,
        'joined_activities_count': joined_activities_count,
        'following_count': following_count,
        'followers_count': followers_count,
        'consecutive_days': consecutive_days,
        'month_checkins': month_checkins,
        'recent_points': recent_points,
        'recent_activities': recent_activities,
        'interests_list': interests_list,
    }
    
    return render(request, 'users/profile.html', context)


@login_required
def settings_view(request):
    """用户设置页面"""
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            user = request.user
            
            # 更新基本信息
            if 'nickname' in data:
                user.nickname = data['nickname']
            if 'signature' in data:
                user.signature = data['signature']
            if 'interests' in data:
                user.interests = data['interests']
            if 'email' in data:
                user.email = data['email']
            if 'phone' in data:
                user.phone = data['phone']
            if 'avatar' in data:
                user.avatar = data['avatar']
            
            user.save()
            
            return JsonResponse({
                'code': 200,
                'message': '保存成功'
            })
            
        except Exception as e:
            return JsonResponse({
                'code': 500,
                'message': f'保存失败：{str(e)}'
            }, status=500)
    
    return render(request, 'users/settings.html')


def forgot_password_view(request):
    """忘记密码"""
    if request.method == 'POST':
        email = request.POST.get('email')
        
        try:
            user = User.objects.get(email=email)
            
            # TODO: 生成重置令牌并发送邮件
            # 这里简化处理
            
            messages.success(request, '密码重置链接已发送到您的邮箱')
            return redirect('users:login')
            
        except User.DoesNotExist:
            messages.error(request, '该邮箱未注册')
    
    return render(request, 'users/forgot_password.html')


@login_required
def messages_view(request):
    """私信列表"""
    # 获取会话列表
    sent_messages = PrivateMessage.objects.filter(sender=request.user)
    received_messages = PrivateMessage.objects.filter(receiver=request.user)
    
    # 获取所有对话用户
    conversation_users = set()
    for msg in sent_messages:
        conversation_users.add(msg.receiver)
    for msg in received_messages:
        conversation_users.add(msg.sender)
    
    context = {
        'conversations': list(conversation_users),
    }
    
    return render(request, 'users/messages.html', context)


# API 视图

@require_http_methods(["POST"])
def send_verification_code(request):
    """发送邮箱验证码"""
    try:
        data = json.loads(request.body)
        email = data.get('email', '').strip()
        
        # 验证邮箱格式
        import re
        if not re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', email):
            return JsonResponse({
                'code': 400,
                'message': '请输入正确的邮箱地址'
            }, status=400)
        
        # 检查发送频率限制（60秒内只能发送一次）
        rate_limit_key = f'email_rate_{email}'
        if cache.get(rate_limit_key):
            return JsonResponse({
                'code': 400,
                'message': '验证码已发送，请60秒后再试'
            }, status=400)
        
        # 生成6位数字验证码
        code = ''.join(random.choices(string.digits, k=6))
        
        # 将验证码存入缓存（有效期10分钟）
        cache_key = f'email_code_{email}'
        cache.set(cache_key, code, 600)
        
        # 设置发送频率限制（60秒）
        cache.set(rate_limit_key, '1', 60)
        
        # 开发环境下直接打印验证码（便于测试）
        if settings.DEBUG:
            print("=" * 60)
            print(f"📧 邮箱验证码（开发环境）")
            print(f"📮 接收邮箱: {email}")
            print(f"🔑 验证码: {code}")
            print(f"⏰ 有效期: 10分钟")
            print("=" * 60)
        
        # 发送邮件验证码
        try:
            send_mail(
                '本地有约 - 注册验证码',
                f'您的验证码是：{code}\n\n验证码10分钟内有效，请勿泄露给他人。\n\n如果这不是您的操作，请忽略此邮件。',
                settings.DEFAULT_FROM_EMAIL,
                [email],
                fail_silently=False,
            )
            
            print(f"✅ 邮件已成功发送到: {email}")
            
            return JsonResponse({
                'code': 200,
                'message': '验证码已发送到您的邮箱，请查收',
                'data': {
                    'code': code if settings.DEBUG else None  # 仅开发环境返回验证码
                }
            })
        except Exception as e:
            print(f"❌ 邮件发送失败！")
            print(f"错误详情: {type(e).__name__}: {e}")
            print(f"邮箱配置:")
            print(f"  - EMAIL_HOST: {settings.EMAIL_HOST}")
            print(f"  - EMAIL_PORT: {settings.EMAIL_PORT}")
            print(f"  - EMAIL_USE_SSL: {settings.EMAIL_USE_SSL}")
            print(f"  - EMAIL_HOST_USER: {settings.EMAIL_HOST_USER}")
            
            # 开发环境下即使邮件发送失败，也返回成功（使用控制台验证码）
            if settings.DEBUG:
                print(f"⚠️  开发环境：邮件发送失败，但验证码已打印在控制台")
                return JsonResponse({
                    'code': 200,
                    'message': '验证码已生成（开发环境：请查看控制台）',
                    'data': {
                        'code': code  # 开发环境返回验证码
                    }
                })
            else:
                return JsonResponse({
                    'code': 500,
                    'message': f'验证码发送失败：{str(e)}'
                }, status=500)
        
    except json.JSONDecodeError:
        return JsonResponse({
            'code': 400,
            'message': '数据格式错误'
        }, status=400)
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': str(e)
        }, status=500)


@login_required
@require_http_methods(["POST"])
def upload_avatar(request):
    """上传头像"""
    try:
        # 检查是否有文件上传
        if 'avatar' not in request.FILES:
            return JsonResponse({
                'code': 400,
                'message': '请选择要上传的图片'
            }, status=400)
        
        avatar_file = request.FILES['avatar']
        
        # 验证文件类型
        allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp']
        if avatar_file.content_type not in allowed_types:
            return JsonResponse({
                'code': 400,
                'message': '不支持的图片格式，请上传 JPG、PNG、GIF 或 WEBP 格式的图片'
            }, status=400)
        
        # 验证文件大小（限制5MB）
        max_size = 5 * 1024 * 1024  # 5MB
        if avatar_file.size > max_size:
            return JsonResponse({
                'code': 400,
                'message': '图片大小不能超过5MB'
            }, status=400)
        
        # 删除旧头像（如果存在）
        if request.user.avatar:
            try:
                import os
                old_avatar_path = request.user.avatar.path
                if os.path.exists(old_avatar_path):
                    os.remove(old_avatar_path)
            except Exception as e:
                print(f"删除旧头像失败: {e}")
        
        # 保存新头像
        request.user.avatar = avatar_file
        request.user.save()
        
        # 返回新头像URL
        avatar_url = request.user.avatar.url if request.user.avatar else None
        
        return JsonResponse({
            'code': 200,
            'message': '头像上传成功',
            'data': {
                'avatar_url': avatar_url
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'上传失败：{str(e)}'
        }, status=500)


@login_required
@require_http_methods(["POST"])
def update_privacy_settings(request):
    """更新隐私设置"""
    try:
        data = json.loads(request.body)
        category = data.get('category')
        field_name = data.get('field_name')
        is_public = data.get('is_public')
        
        request.user.update_privacy_setting(category, field_name, is_public)
        
        return JsonResponse({
            'code': 200,
            'message': '设置已更新',
            'data': request.user.privacy_settings
        })
        
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': str(e)
        }, status=500)


@login_required
@require_http_methods(["POST"])
def follow_user(request, user_id):
    """关注用户"""
    try:
        target_user = get_object_or_404(User, id=user_id)
        
        if request.user == target_user:
            return JsonResponse({
                'code': 400,
                'message': '不能关注自己'
            }, status=400)
        
        # 检查是否已关注
        if UserFollow.objects.filter(follower=request.user, following=target_user).exists():
            return JsonResponse({
                'code': 400,
                'message': '已经关注过了'
            }, status=400)
        
        # 创建关注关系
        UserFollow.objects.create(
            follower=request.user,
            following=target_user
        )
        
        return JsonResponse({
            'code': 200,
            'message': '关注成功'
        })
        
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': str(e)
        }, status=500)


@login_required
@require_http_methods(["POST"])
def unfollow_user(request, user_id):
    """取消关注"""
    try:
        target_user = get_object_or_404(User, id=user_id)
        
        UserFollow.objects.filter(
            follower=request.user,
            following=target_user
        ).delete()
        
        return JsonResponse({
            'code': 200,
            'message': '已取消关注'
        })
        
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': str(e)
        }, status=500)


@require_http_methods(["GET"])
def get_following_list(request, user_id):
    """获取关注列表"""
    user = get_object_or_404(User, id=user_id)
    
    following_list = UserFollow.objects.filter(follower=user).select_related('following')
    
    data = [{
        'id': f.following.id,
        'username': f.following.username,
        'nickname': f.following.nickname,
        'avatar': f.following.avatar,
    } for f in following_list]
    
    return JsonResponse({
        'code': 200,
        'data': data
    })


@require_http_methods(["GET"])
def get_followers_list(request, user_id):
    """获取粉丝列表"""
    user = get_object_or_404(User, id=user_id)
    
    followers_list = UserFollow.objects.filter(following=user).select_related('follower')
    
    data = [{
        'id': f.follower.id,
        'username': f.follower.username,
        'nickname': f.follower.nickname,
        'avatar': f.follower.avatar,
    } for f in followers_list]
    
    return JsonResponse({
        'code': 200,
        'data': data
    })
